package net.jgrm.common.db.dao;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;

/**
 * 基础DAO抽象类
 * 封装通用的数据访问操作
 *
 * @param <M> Mapper类型
 * @param <T> 实体类型
 * @author: houyong
 * @date: 2025年09月19日
 */
public abstract class BaseDao<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> {

    @Autowired
    protected M baseMapper;

    /**
     * 根据ID查询
     *
     * @param id 主键ID
     * @return 实体对象
     */
    public T findById(Long id) {
        return baseMapper.selectById(id);
    }

    /**
     * 查询所有记录
     *
     * @return 实体列表
     */
    public List<T> findAll() {
        return baseMapper.selectList(null);
    }

    /**
     * 根据条件查询
     *
     * @param queryWrapper 查询条件
     * @return 实体列表
     */
    public List<T> findByCondition(QueryWrapper<T> queryWrapper) {
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 使用Lambda表达式查询
     *
     * @param lambdaQueryWrapper Lambda查询条件
     * @return 实体列表
     */
    public List<T> findByLambda(LambdaQueryWrapper<T> lambdaQueryWrapper) {
        return baseMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 分页查询
     *
     * @param pageNum  页码
     * @param pageSize 每页条数
     * @return 分页结果
     */
    public List<T> findPage(int pageNum, int pageSize) {
        IPage page = new Page<>(pageNum, pageSize);
        return page(page).getRecords();
    }

    /**
     * 新增实体
     *
     * @param entity 实体对象
     * @return 是否成功
     */
    public boolean saveEntity(T entity) {
        return save(entity);
    }

    /**
     * 批量新增
     *
     * @param entities 实体列表
     * @return 是否成功
     */
    public boolean saveBatchEntities(List<T> entities) {
        return saveBatch(entities);
    }

    /**
     * 更新实体
     *
     * @param entity 实体对象
     * @return 是否成功
     */
    public boolean updateEntity(T entity) {
        return updateById(entity);
    }

    /**
     * 根据条件更新
     *
     * @param entity        实体对象
     * @param updateWrapper 更新条件
     * @return 是否成功
     */
    public boolean updateByCondition(T entity, UpdateWrapper<T> updateWrapper) {
        return update(entity, updateWrapper);
    }

    /**
     * 使用Lambda表达式更新
     *
     * @param entity              实体对象
     * @param lambdaUpdateWrapper Lambda更新条件
     * @return 是否成功
     */
    public boolean updateByLambda(T entity, LambdaUpdateWrapper<T> lambdaUpdateWrapper) {
        return update(entity, lambdaUpdateWrapper);
    }

    /**
     * 批量更新
     *
     * @param entities 实体列表
     * @return 是否成功
     */
    public boolean updateBatchEntities(List<T> entities) {
        return updateBatchById(entities);
    }

    /**
     * 根据ID删除
     *
     * @param id 主键ID
     * @return 是否成功
     */
    public boolean deleteById(Long id) {
        return removeById(id);
    }

    /**
     * 批量删除
     *
     * @param ids ID列表
     * @return 是否成功
     */
    public boolean deleteBatchIds(List<Long> ids) {
        return removeByIds(ids);
    }

    /**
     * 根据条件删除
     *
     * @param queryWrapper 删除条件
     * @return 是否成功
     */
    public boolean deleteByCondition(QueryWrapper<T> queryWrapper) {
        return remove(queryWrapper);
    }


    /**
     * 根据条件统计记录数
     *
     * @param queryWrapper 统计条件
     * @return 符合条件的记录数
     */
    public int countByCondition(QueryWrapper<T> queryWrapper) {
        return
                (int) count(queryWrapper);
    }

    /**
     * 执行自定义SQL查询
     *
     * @param sql    SQL语句
     * @param params 参数
     * @return 查询结果
     */
    public List<Map<String, Object>> queryBySql(String sql, Object... params) {
        // 注意：实际项目中应使用安全的SQL执行方式，避免SQL注入
        return baseMapper.selectMaps(new QueryWrapper<T>().apply(sql, params));
    }
}